/*
 *  Copyright © OpenAtom Foundation.
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.openatom.ubml.model.common.definition.commonmodel.json.element;

import com.fasterxml.jackson.core.JsonParser;
import org.openatom.ubml.model.common.definition.cef.collection.GspFieldCollection;
import org.openatom.ubml.model.common.definition.cef.entity.GspCommonField;
import org.openatom.ubml.model.common.definition.cef.json.SerializerUtils;
import org.openatom.ubml.model.common.definition.cef.json.element.CefFieldDeserializer;
import org.openatom.ubml.model.common.definition.cef.json.element.GspAssociationDeserializer;
import org.openatom.ubml.model.common.definition.commonmodel.collection.GspElementCollection;
import org.openatom.ubml.model.common.definition.commonmodel.entity.GspCommonElement;
import org.openatom.ubml.model.common.definition.commonmodel.entity.element.ElementCodeRuleConfig;
import org.openatom.ubml.model.common.definition.commonmodel.entity.element.GspBillCodeGenerateOccasion;
import org.openatom.ubml.model.common.definition.commonmodel.entity.element.GspBillCodeGenerateType;
import org.openatom.ubml.model.common.definition.commonmodel.json.CommonModelNames;

import static com.fasterxml.jackson.core.JsonToken.FIELD_NAME;

/**
 * The Json Parser Of  CmELement
 *
 * @ClassName: VersionControlInfo
 * @Author: Benjamin Gong
 * @Date: 2021/1/11 17:13
 * @Version: V1.0
 */
public abstract class CmElementDeserializer extends CefFieldDeserializer {
    @Override
    protected final GspCommonField CreateField() {
        return createElement();
    }


    @Override
    protected final boolean readExtendFieldProperty(GspCommonField item, String propName, JsonParser jsonParser) {
        boolean result = true;
        GspCommonElement field = (GspCommonElement)item;
        switch (propName) {
            case CommonModelNames.BILL_CODE_CONFIG:
                field.setBillCodeConfig(readBillCodeConfig(jsonParser));
                break;
            case CommonModelNames.COLUMN_ID:
                field.setColumnID(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case CommonModelNames.READONLY:
                field.setReadonly(SerializerUtils.readPropertyValue_boolean(jsonParser));
                break;
            case CommonModelNames.IS_CUSTOM_ITEM:
                field.setIsCustomItem(SerializerUtils.readPropertyValue_boolean(jsonParser));
                break;
            case CommonModelNames.BELONG_MODEL_ID:
                field.setBelongModelID(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            default:
                result = readExtendElementProperty(field, propName, jsonParser);
                break;
        }
        return result;
    }

    protected abstract GspCommonElement createElement();

    @Override
    protected GspFieldCollection CreateFieldCollection() {
        return new GspElementCollection(null);
    }

    protected boolean readExtendElementProperty(GspCommonElement field, String propName, JsonParser jsonParser) {
        return false;
    }


    private ElementCodeRuleConfig readBillCodeConfig(JsonParser jsonParser) {
        ElementCodeRuleConfig elementCodeRuleConfig = new ElementCodeRuleConfig();
        if (SerializerUtils.readNullObject(jsonParser)) {
            return elementCodeRuleConfig;
        }

        SerializerUtils.readStartObject(jsonParser);
        while (jsonParser.getCurrentToken() == FIELD_NAME) {
            String propName = SerializerUtils.readPropertyName(jsonParser);
            readBillCodeConfigPropertyValue(elementCodeRuleConfig, propName, jsonParser);
        }
        SerializerUtils.readEndObject(jsonParser);
        return elementCodeRuleConfig;
    }

    private void readBillCodeConfigPropertyValue(ElementCodeRuleConfig elementCodeRuleConfig, String propName, JsonParser jsonParser) {
        switch (propName) {
            case CommonModelNames.BILL_CODE:
                elementCodeRuleConfig.setCanBillCode(SerializerUtils.readPropertyValue_boolean(jsonParser));
                break;
            case CommonModelNames.BILL_CODE_ID:
                elementCodeRuleConfig.setBillCodeID(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case CommonModelNames.BILL_CODE_NAME:
                elementCodeRuleConfig.setBillCodeName(SerializerUtils.readPropertyValue_String(jsonParser));
                break;
            case CommonModelNames.CODE_GENERATE_OCCASION:
                elementCodeRuleConfig.setCodeGenerateOccasion(SerializerUtils.readPropertyValue_Enum(jsonParser, GspBillCodeGenerateOccasion.class, GspBillCodeGenerateOccasion.values()));
                break;
            case CommonModelNames.CODE_GENERATE_TYPE:
                elementCodeRuleConfig.setCodeGenerateType(SerializerUtils.readPropertyValue_Enum(jsonParser, GspBillCodeGenerateType.class, GspBillCodeGenerateType.values()));
                break;
            default:
                throw new RuntimeException(String.format("MappingInfoDeserializer未识别的属性名：%1$s", propName));
        }
    }

    @Override
    protected GspAssociationDeserializer CreateGspAssoDeserializer() {
        return new GspCommonAssociationDeserializer(this);
    }
}
